package com.hspedu.qqclient.service;

/**
 * @author 吴宇~
 * @motto 我亦无他，唯手熟尔。
 * @edition jdk1.8
 * @reflection 0-1 喧闹任其喧闹，自由我自为之，我自风情万种，与世无争。
 * @date 2023/03/20/16:28
 */


import com.hspedu.qqcommon.Message;
import com.hspedu.qqcommon.MessageType;
import com.hspedu.qqcommon.User;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;

/**
 * 该类完成用户登录和用户注册等等功能
 */
public class UserClientService {                //其实就是这儿写了几个方法而已，没什么大不了的
    //我们可能在其他要是有user信息，因此。做成成员属性
    private User u = new User();
    //因为socket在其他地方也可能用，所以我们把它做成属性
    private Socket socket = null;

    //到服务器验证用户是否合法
    public boolean checkUser(String userID, String pwd) {
        boolean b = false;
        /**
         * 记录一下，我在这儿输错了。
         * 写了两句 u.setPasswd(pwd);，导致没有吧id的值传进去
         */
        u.setUserID(userID);
        u.setPasswd(pwd);
        //现在我们可以连接到服务端，发送u对象
        try {
            //连接到服务器，发送u对象
            socket = new Socket(InetAddress.getLocalHost(), 9999);
            //得到ObjectOutputStream对象,准备把这个对象发过去,还记得这个输出流吗，存的是对象
            OutputStream os = socket.getOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(os);
            oos.writeObject(u);


            //读取从服务端回复的Message对象
            InputStream inputStream = socket.getInputStream();
            ObjectInputStream ois = new ObjectInputStream(inputStream);
            Message ms = (Message) ois.readObject();

            if (ms.getMesType().equals(MessageType.MESSAGE_LOGIN_SUCCEED)) {//表示登录成功
                b = true;
                //!!!!!创建一个线程和服务器端保持通讯的线程->再次创建一个类。ClientConnectServerThread
                //等待。。
                ClientConnectServerThread clientConnectServerThread = new ClientConnectServerThread(socket);
                //启动客户端的线程
                clientConnectServerThread.start();
                //为了后面客户端的扩展， 我们将线程放入到集合中管理
                MangerClientConnectServerThread.addClientConnectServerThread(userID, clientConnectServerThread);

            } else {
                //如果登录失败，线程是没有创建的，不能启动和服务器通信的线程
                socket.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return b;
    }

    //向服务器端请求在线用户列表
    public void onlineFriendList(){
        //发送一个MESSAGE，类型String MESSAGE_GET_ONLINE_FRIEND="4";//要求返回在线用户列表
        Message message = new Message();
        message.setMesType(MessageType.MESSAGE_GET_ONLINE_FRIEND);
        /**
         * 这儿得设置一下发送者是谁，谁启用这个线程，这个发送者就是谁
         */
        message.setSender(u.getUserID());

        //发送给服务器
        //应该得到当前这个线程的Socket。对应的ObjectOutputStream对象
        /**
         ****完美诠释了在java中万物皆对象
         * ClientConnectServerThread clientConnectServerThread = MangerClientConnectServerThread.getClientConnectServerThread(u.getUserID());
         *         Socket socket = clientConnectServerThread.getSocket();
         *         OutputStream outputStream = socket.getOutputStream();
         *         ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
         *
         *         下面就上面的这个意思
         */

        try {
            //这段代码就是客户端告诉服务端我要  你返回在线用户列表，
            ObjectOutputStream oos =
                    new ObjectOutputStream(MangerClientConnectServerThread.getClientConnectServerThread(u.getUserID()).getSocket().getOutputStream());
            oos.writeObject(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //编写方法退出客户端并给服务端发送一个退出系统的message对象
    public void logout(){
        Message message = new Message();
        message.setSender(u.getUserID());//一定要指定我是哪个客户端
        message.setMesType(MessageType.MESSAGE_CLIENT_EXIT);
        try {
            ObjectOutputStream oos = new ObjectOutputStream(MangerClientConnectServerThread.getClientConnectServerThread(u.getUserID()).getSocket().getOutputStream());
            /**两种写法，上面这种更好吧
             *ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
             *
             */
            /**
             * 自己找到bug的感觉真是不错，这个bug是没有把这条写这句代码
             * oos.writeObject(message);客户端自己是退出了，但是没有发送这个消息，导致服务端是退出了，
             *客户端对应的这个线程还在那儿对那儿等，但是客户端消息也灵通，客户端在那人不停的等，服务端退了，
             * 骂骂咧咧的报了数不完的异常
             */
            oos.writeObject(message);
            System.out.println(u.getUserID()+"退出了系统");
            System.exit(0);//结束进程。进程启动主线程，主线程启动子线程，进程结束则全部结束，主线程结束子线程不一定结束
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //
}
